﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevComponents.DotNetBar.Metro;
using Devsoft.Utilities;
using Microsoft.Office.Interop.Excel;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using PlatForm.Controller;
using PlatForm.DataLayer;

namespace PlatForm.Presentation
{
    public partial class frmPick : MetroForm
    {
        private SupplierController supplierCtrl = new SupplierController();

        private PackageController packageCtrl = new PackageController();

        private OrderController orderCtrl = new OrderController();

        private ArticleController artCtrl = new ArticleController();

        private List<PickingDetail> lstPickingDetail = new List<PickingDetail>();

        private List<Package> lstPackage = new List<Package>();

        private List<Order> lstOrder = new List<Order>();

        public frmPick()
        {
            InitializeComponent();
            dgvArticle.AutoGenerateColumns = false;
            dGVSupplier.AutoGenerateColumns = false;
            dgvOrder.AutoGenerateColumns = false;

            var lstSupplier = supplierCtrl.GetList();
            dGVSupplier.DataSource = lstSupplier;

            lstPackage = packageCtrl.GetList();
           
        }

        #region Shortcut Keys

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.S | Keys.Control:
                    SavePickingDetail();
                    break;
                case Keys.P | Keys.Control:
                    PickingDetailValueChanged();
                    if (dgvPickingDetail.CurrentRow != null)
                    {
                        PrintOrder(dgvPickingDetail.CurrentRow.Index);
                        SavePickingDetail();
                    }
                    break;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
        
        #endregion

        private void dGVSupplier_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dGVSupplier.CurrentRow != null) LoadArticleBySupplier(dGVSupplier.CurrentRow.Index);
        }

        private void dgvArticle_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgvArticle.CurrentRow != null) LoadOrderByArticle(dgvArticle.CurrentRow.Index);
        }

        #region Save Picking detail
        public void SavePickingDetail()
        {
            PickingDetailValueChanged();
            if (dgvPickingDetail.CurrentRow != null &&
                dgvPickingDetail.CurrentRow.Index < dgvPickingDetail.Rows.Count - 1)
            {
                foreach (DataGridViewCell cell in dgvPickingDetail.CurrentRow.Cells)
                {
                    if (cell.Value == null && cell.ColumnIndex > 0)
                    {
                        cell.Value = "0";
                    }
                    if (cell.ColumnIndex == 10)
                        cell.Value = "Print (Ctrl+P)";
                }

                if (dgvPickingDetail.CurrentRow.Cells[3].Value.ToString() != "0")
                {
                    PickingDetailValueChanged();
                    var pik =
                        Picking.Objects.FirstOrDefault(
                            x => x.PIK_No == int.Parse(lblPickingNo.Text.Split(':')[1]));
                    var pikD =
                        PickingDetail.Objects.FirstOrDefault(
                            x => x.PIKD_No == int.Parse(dgvPickingDetail.CurrentRow.Cells[0].Value == null
                                                            ? "0"
                                                            : dgvPickingDetail.CurrentRow.Cells[0].Value
                                                                                                  .ToString()));

                    if (pik != null)
                    {
                        var pd = new PickingDetail()
                        {
                            PIKD_No =
                                int.Parse(dgvPickingDetail.CurrentRow.Cells[0].Value == null
                                              ? "0"
                                              : dgvPickingDetail.CurrentRow.Cells[0].Value.ToString()),
                            PIK_No = int.Parse(lblPickingNo.Text.Split(':')[1]),
                            Net = float.Parse(dgvPickingDetail.CurrentRow.Cells[1].Value.ToString()),
                            PIK_Time =
                                int.Parse(dgvPickingDetail.CurrentRow.Cells[2].Value.ToString()),
                            Gross =
                                float.Parse(dgvPickingDetail.CurrentRow.Cells[3].Value.ToString()),
                            Lon = int.Parse(dgvPickingDetail.CurrentRow.Cells[4].Value.ToString()),
                            Trung = int.Parse(dgvPickingDetail.CurrentRow.Cells[5].Value.ToString()),
                            Dau = int.Parse(dgvPickingDetail.CurrentRow.Cells[6].Value.ToString()),
                            Be = int.Parse(dgvPickingDetail.CurrentRow.Cells[7].Value.ToString()),
                            NaturalLoss =
                                float.Parse(dgvPickingDetail.CurrentRow.Cells[8].Value.ToString()),
                            ProcessLoss =
                                float.Parse(dgvPickingDetail.CurrentRow.Cells[9].Value.ToString()),
                            LastUpdated = DateTime.Now
                        };
                        if (pikD == null)
                        {
                            pd.Insert();
                            dgvPickingDetail.CurrentRow.Cells[0].Value = pd.PIKD_No;
                            pik.DELI_QTY = pik.DELI_QTY + pd.Net;
                            pik.Package += pd.Lon + pd.Trung + pd.Dau + pd.Be;
                            pik.PickDate = DateTime.Now.Date;
                            
                            pik.Update();

                            var order =
                                Order.Objects.FirstOrDefault(
                                    x => x.ORD_No == dgvOrder.CurrentRow.Cells[0].Value.ToString());
                            if (order != null)
                            {
                                order.RECE_QTY = pik.DELI_QTY;
                                order.Update(true);
                                if (dgvOrder.CurrentRow != null)
                                {
                                    dgvOrder.CurrentRow.Cells[3].Value = pik.DELI_QTY;
                                    dgvOrder.CurrentRow.Cells[4].Value = order.DELI_QTY - order.RECE_QTY;
                                }
                            }
                        }
                        else
                        {
                            var lstPick = PickingDetail.Objects.Where(x => x.PIK_No == pd.PIK_No);
                            pd.Update(true);
                            dgvPickingDetail.CurrentRow.Cells[0].Value = pd.PIKD_No;
                            pik.DELI_QTY =
                                lstPick.Sum(x => x.Net);
                            pik.Package = lstPick.Sum(x => x.Lon) + lstPick.Sum(x => x.Trung) +
                                          lstPick.Sum(x => x.Dau) + lstPick.Sum(x => x.Be);
                            pik.PickDate = DateTime.Now.Date;
                            
                            pik.Update();

                            var order =
                                Order.Objects.FirstOrDefault(
                                    x => x.ORD_No == dgvOrder.CurrentRow.Cells[0].Value.ToString());
                            if (order != null)
                            {
                                order.RECE_QTY = pik.DELI_QTY;
                                order.Update(true);
                                if (dgvOrder.CurrentRow != null)
                                {
                                    dgvOrder.CurrentRow.Cells[3].Value = pik.DELI_QTY;
                                    dgvOrder.CurrentRow.Cells[4].Value = order.DELI_QTY - order.RECE_QTY;
                                }
                            }
                        }
                        
                    }
                }
            }
        }
        #endregion

        #region Load Article By Supplier
        private void LoadArticleBySupplier(int rowIndex)
        {
                var lstArt = artCtrl.GetBySuppl(dGVSupplier.Rows[rowIndex].Cells[0].Value.ToString());
                dgvArticle.DataSource = lstArt;
                lblSUPPL_Name.Text = "Supplier: "+ dGVSupplier.Rows[rowIndex].Cells[1].Value;
        }
        #endregion

        #region Load Order By Article

        private void LoadOrderByArticle(int rowIndex)
        {
            lstOrder = orderCtrl.GetByART(dgvArticle.Rows[rowIndex].Cells[0].Value.ToString());
            dgvOrder.DataSource = lstOrder;

            lblArt_Name.Text = "Article: " + dgvArticle.Rows[rowIndex].Cells[1].Value;

            foreach (DataGridViewRow row in dgvOrder.Rows)
            {
                row.Cells[4].Value = float.Parse(row.Cells[2].Value.ToString()) -
                                     float.Parse(row.Cells[3].Value.ToString());

                DataGridViewCell cell = row.Cells[5]; //Column Index
                cell.Value = "Picking";

                var pik = Picking.Objects.FirstOrDefault(x => x.ORD_No == row.Cells[0].Value.ToString());
                if (pik != null)
                {
                    row.Cells[5].Value = "Picking No:" + pik.PIK_No;
                }
            }
        }

        #endregion
        
        private void dgvOrder_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 5)
            {
                if (dgvOrder.CurrentRow != null && (string)dgvOrder.CurrentRow.Cells[5].Value == "Picking")
                {
                    if (dGVSupplier.CurrentRow != null && dgvArticle.CurrentRow != null)
                    {
                        var picking = new Picking()
                        {
                            ST_No = dgvOrder.CurrentRow.Cells[1].Value.ToString(),
                            SUPPL_No = dGVSupplier.CurrentRow.Cells[0].Value.ToString(),
                            ORD_No = dgvOrder.CurrentRow.Cells[0].Value.ToString(),
                            ART_No = dgvArticle.CurrentRow.Cells[0].Value.ToString(),
                            PickDate = DateTime.Now.Date
                        };
                        picking.Insert(true);
                        dgvOrder.CurrentRow.Cells[5].Value = "Picking No:" + picking.PIK_No;
                        lblPickingNo.Text = picking.PIK_No.ToString(CultureInfo.InvariantCulture);
                    }
                }
                else
                {
                    lstPickingDetail =
                        PickingDetail.Objects.Where(
                            x =>
                            x.PIK_No == int.Parse(dgvOrder.CurrentRow.Cells[5].Value.ToString().Split(':')[1].Trim())).
                                      ToList();
                    dgvPickingDetail.Rows.Clear();
                    foreach (var p in lstPickingDetail)
                    {
                        dgvPickingDetail.Rows.Add(p.PIKD_No, p.Net, p.PIK_Time, p.Gross, p.Lon, p.Trung, p.Dau,
                                                  p.Be, p.NaturalLoss, p.ProcessLoss);
                    }
                    foreach (DataGridViewRow r in dgvPickingDetail.Rows)
                    {
                        if (r.Cells[10].ColumnIndex == 10)
                            r.Cells[10].Value = "Print (Ctrl+P)";
                    }
                }
                if (dgvOrder.CurrentRow != null) lblPickingNo.Text = dgvOrder.CurrentRow.Cells[5].Value.ToString();
                dgvPickingDetail.Enabled = true;
            }
        }

        private void bindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
            PickingDetailValueChanged();
            foreach (DataGridViewRow row in dgvPickingDetail.Rows)
            {
                if (row.Index < dgvPickingDetail.Rows.Count - 1)
                {
                    foreach (DataGridViewCell cell in row.Cells)
                    {
                        if (cell.Value == null)
                        {
                            cell.Value = "0";
                        }
                        if (cell.ColumnIndex == 10)
                            cell.Value = "Print (Ctrl+P)";
                    }

                    if (row.Cells[3].Value.ToString() != "0")
                    {
                        var pd = new PickingDetail()
                        {
                            PIKD_No =
                                int.Parse(row.Cells[0].Value == null ? "0" : row.Cells[0].Value.ToString()),
                            PIK_No = int.Parse(lblPickingNo.Text.Split(':')[1]),
                            Net = float.Parse(row.Cells[1].Value.ToString()),
                            PIK_Time = int.Parse(row.Cells[2].Value.ToString()),
                            Gross = float.Parse(row.Cells[3].Value.ToString()),
                            Lon = int.Parse(row.Cells[4].Value.ToString()),
                            Trung = int.Parse(row.Cells[5].Value.ToString()),
                            Dau = int.Parse(row.Cells[6].Value.ToString()),
                            Be = int.Parse(row.Cells[7].Value.ToString()),
                            NaturalLoss = float.Parse(row.Cells[8].Value.ToString()),
                            ProcessLoss = float.Parse(row.Cells[9].Value.ToString()),
                            LastUpdated = DateTime.Now
                        };

                        pd.InsertOrUpdate();
                    }
                }
            }
        }

        public void PickingDetailValueChanged()
        {
            if (dgvPickingDetail.CurrentRow != null)
            {
                foreach (DataGridViewCell cell in dgvPickingDetail.CurrentRow.Cells)
                {
                    if (cell.Value == null && cell.ColumnIndex>0)
                    {
                        cell.Value = "0";
                    }
                    if (cell.ColumnIndex == 10)
                        cell.Value = "Print (Ctrl+P)";
                }

                var l = int.Parse(dgvPickingDetail.CurrentRow.Cells[4].Value.ToString());
                var t = int.Parse(dgvPickingDetail.CurrentRow.Cells[5].Value.ToString());
                var d = int.Parse(dgvPickingDetail.CurrentRow.Cells[6].Value.ToString());
                var b = int.Parse(dgvPickingDetail.CurrentRow.Cells[7].Value.ToString());
                var pl = lstPackage.FirstOrDefault(x => x.PCK_Name == "Lon");
                var pt = lstPackage.FirstOrDefault(x => x.PCK_Name == "Trung");
                var pd = lstPackage.FirstOrDefault(x => x.PCK_Name == "Dau");
                var pb = lstPackage.FirstOrDefault(x => x.PCK_Name == "Be");
                var totalNaturalLoss = l * pl.NaturalLoss + t * pt.NaturalLoss + d * pd.NaturalLoss + b * pb.NaturalLoss;
                var totalProcessLoss = l * pl.ProcessLoss + t * pt.ProcessLoss + d * pd.ProcessLoss + b * pb.ProcessLoss;

                dgvPickingDetail.CurrentRow.Cells[8].Value = totalNaturalLoss;
                dgvPickingDetail.CurrentRow.Cells[9].Value = totalProcessLoss;

                var lossNet = l * pl.NET + t * pt.NET + d * pd.NET + b * pb.NET + totalNaturalLoss + totalProcessLoss;

                dgvPickingDetail.CurrentRow.Cells[1].Value =
                    float.Parse(dgvPickingDetail.CurrentRow.Cells[3].Value.ToString()) - lossNet;

            }
        }

        private void dgvPickingDetail_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            PickingDetailValueChanged();
        }

        public void PrintOrder(int rowindex)
        {
            PickingDetailValueChanged();
            if (dgvOrder.CurrentRow != null && dgvPickingDetail.CurrentRow != null)
            {
                var tempFile = new FileInfo("printFile.xlsx");
                if (tempFile.Exists)
                {
                    tempFile.Delete(); // ensures we create a new workbook
                    tempFile = new FileInfo("printFile.xlsx");
                }
                using (var package = new ExcelPackage(tempFile))
                {
                    // add a new worksheet to the empty workbook
                    ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("PickingPrint");

                    //format table
                    worksheet.Cells.Style.Border.Right.Style = ExcelBorderStyle.Thin;
                    worksheet.Cells.Style.Border.Right.Color.SetColor(Color.LightGray);
                    worksheet.Cells["A1:B2"].Merge = true;
                    if (dgvOrder.CurrentRow != null)
                        worksheet.Cells["A1:B2"].Value = dgvOrder.CurrentRow.Cells[2].Value; //ORD Quantity;

                    worksheet.Cells["C1:D1"].Merge = true;
                    worksheet.Cells["C1:D1"].Value = "Date";

                    worksheet.Cells["C2:D2"].Merge = true;
                    worksheet.Cells["C2:D2"].Value = DateTime.Now.Day + "/" + DateTime.Now.Month;

                    worksheet.Cells["A3:D3"].Merge = true;
                    var storeName =
                        Store.Objects.FirstOrDefault(x => x.ST_No == dgvOrder.CurrentRow.Cells[1].Value.ToString());
                    worksheet.Cells["A3:D3"].Value = storeName != null ? storeName.ST_Name : "";

                    worksheet.Cells["A4:D4"].Merge = true;
                    worksheet.Cells["A4:D4"].Value = dgvOrder.CurrentRow.Cells[1].Value.ToString();

                    worksheet.Cells["A5:D5"].Merge = true;
                    worksheet.Cells["A5:D5"].Value = dgvOrder.CurrentRow.Cells[0].Value.ToString();

                    worksheet.Cells["A6"].Value = "NET";
                    worksheet.Cells["B6"].Value = "GROSS";
                    worksheet.Cells["C6"].Value = "NL";
                    worksheet.Cells["D6"].Value = "PL";

                    worksheet.Cells["A7"].Value = dgvPickingDetail.Rows[rowindex].Cells[1].Value.ToString();
                    worksheet.Cells["B7"].Value = dgvPickingDetail.Rows[rowindex].Cells[3].Value.ToString();
                    worksheet.Cells["C7"].Value = dgvPickingDetail.Rows[rowindex].Cells[8].Value.ToString();
                    worksheet.Cells["D7"].Value = dgvPickingDetail.Rows[rowindex].Cells[9].Value.ToString();

                    worksheet.Cells["A8:B8"].Merge = true;
                    worksheet.Cells["A8:B8"].Value = "Note";
                    worksheet.Cells["C8:D8"].Merge = true;
                    worksheet.Cells["C8:D8"].Value = int.Parse(dgvPickingDetail.Rows[rowindex].Cells[4].Value.ToString()) + int.Parse(dgvPickingDetail.Rows[rowindex].Cells[5].Value.ToString()) + int.Parse(dgvPickingDetail.Rows[rowindex].Cells[6].Value.ToString()) + int.Parse(dgvPickingDetail.Rows[rowindex].Cells[7].Value.ToString()) + " Package(s)";

                    worksheet.Cells["A1:D8"].Style.Border.Top.Style = ExcelBorderStyle.Medium;
                    worksheet.Cells["A1:D8"].Style.Border.Bottom.Style = ExcelBorderStyle.Medium;
                    worksheet.Cells["A1:D8"].Style.Border.Left.Style = ExcelBorderStyle.Medium;
                    worksheet.Cells["A1:D8"].Style.Border.Right.Style = ExcelBorderStyle.Medium;
                    worksheet.Cells.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                    worksheet.Cells.Style.VerticalAlignment = ExcelVerticalAlignment.Center;

                    worksheet.Cells.AutoFitColumns(0); //Autofit columns for all cells
                    worksheet.DefaultRowHeight = 30;


                    package.Save();
                }
                var excelApp = new Microsoft.Office.Interop.Excel.Application();

                // Open the Workbook:
                Workbook wb = excelApp.Workbooks.Open(tempFile.FullName,
                                                      Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                                      Type.Missing,
                                                      Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                                      Type.Missing,
                                                      Type.Missing, Type.Missing, Type.Missing, Type.Missing);

                var ws = (Worksheet)wb.Worksheets[1];

                // Print out 1 copy to the default printer:
                ws.PrintOut(
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                    Type.Missing, Type.Missing, Type.Missing, Type.Missing);

                // Cleanup:
                GC.Collect();
                GC.WaitForPendingFinalizers();

                Marshal.FinalReleaseComObject(ws);

                wb.Close(false, Type.Missing, Type.Missing);
                Marshal.FinalReleaseComObject(wb);

                excelApp.Quit();
                Marshal.FinalReleaseComObject(excelApp);
            }
        }

        private void dgvPickingDetail_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 10)
            {
                if (dgvPickingDetail.CurrentRow != null)
                {
                    PrintOrder(dgvPickingDetail.CurrentRow.Index);
                    SavePickingDetail();
                }
            }
        }

        private void frmPick_Load(object sender, EventArgs e)
        {
            if (dGVSupplier.Rows.Count >= 1)
            {
                dGVSupplier.Rows[0].Selected = true;
                LoadArticleBySupplier(dGVSupplier.SelectedRows[0].Index);
                if (dgvArticle.Rows.Count >= 1)
                {
                    dgvArticle.Rows[0].Selected = true;
                    LoadOrderByArticle(dgvArticle.SelectedRows[0].Index);
                }
            }
        }

        private void txtSUPPL_No_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                try
                {
                    foreach (DataGridViewRow r in dGVSupplier.Rows)
                    {
                        if (r.Cells[0].Value.Equals(txtSUPPL_No.Text.Trim()))
                        {
                            r.Selected = true;
                            LoadArticleBySupplier(r.Index);
                            break;
                        }
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }
        

        private void txtART_No_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                try
                {
                    foreach (DataGridViewRow r in dgvArticle.Rows)
                    {
                        if (r.Cells[0].Value.Equals(txtART_No.Text.Trim()))
                        {
                            r.Selected = true;
                            LoadOrderByArticle(r.Index);
                            break;
                        }
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }
        
    }
}
